on idle -- call ShowMenu every so often just in case our menus vanished
global menu1, menu2, lastTick
if (the ticks-lastTick)>120 then -- gives better performance than on every iteration
put the ticks into lastTick
ShowMenu(menu1)
ShowMenu(menu2)
end if
pass idle
end idle
on placeMark lineNum
-- put name of card into array listofCards
-- Called by closeStack to keep track of last card viewed in each stack.
global listofCards, stackRef
put the long name of this card into line stackRef of listOfCards
end placeMark
on goPlaces stackName, lineNum
-- used to return to placeMark
-- called by Menu 1 selections to return to last card viewed.
global listofCards
delete first char of stackName
delete last char of stackName
if line lineNum of listofCards contains stackName then
go to (line lineNum of listofCards)
else
go to stackName
end if
end goPlaces
on openSection menuRef
--called by Section openCard handler to put away links and topics.
--BeenHereBefore keeps track of last section visited.
global menu2,BeenHereBefore
checkmenu menu2,menuRef,true
put the short name of this card into thisSection
if beenHereBefore is not thisSection then
put empty into card field "lastTopic"
else
get card field "lastTopic"
if it is not empty then
send mouseUp to card button ("topic" & it)
end if
end if
put thisSection into BeenHereBefore
end openSection
on closeSection menuRef
--called by Section closeCard handler to put away links and topics.
--Both are put away when you leave the section card, but OpenSection
--will reopen the topic field if this section is the last one visited.
global menu2
checkmenu menu2,menuRef,false
set lockScreen to true
get card field "lastTopic"
if it is not empty then
set the style of card button it to transparent
set hilite of card button ("Topic"&it) to false
hide card field "Topics"
hide card button "Topics"
hide card button "Box"
end if
if hilite of background button "LinkUp" is true then
hide background button "Links"
hide card field "Links"
set the hilite of background button "LinkUp" to false
end if
end closeSection
---String search handlers
on mouseUp
--catch all clicks on fields and get the word clicked on for search
if the target contains "field" then
getkey
end if
end mouseUp
on goSearch
--Called by squirrel icon to prompt for Command or Keyword search.
answer "Go to UNIX Command or Find Keyword?" with "Command" or "Keyword" or "Cancel"
if it is "Cancel" then exit goSearch
if it is "Command" then
askCommand
else
headSearch
end if
end goSearch
on askCommand
--Called by goSearch to look up UNIX command.
--Also marks current card.
global whereToGoBack
Ask "What UNIX command?"
if it is empty then exit askCommand
set cursor to 4
if the number of chars in it is 1 then
set lockScreen to true
go to first card of stack "Commands"
find it in field 1
repeat until the short name of this background is "Commands"
find it in field 1
end repeat
set lockScreen to false
else
go to card (it) of stack "Commands"
if the result is not empty then
answer quote & it & quote && "command not found"
exit askCommand
end if
end if
push recent card
pop card into WhereToGoBack
end askCommand
on headSearch
--Called by goSearch; look for search string in heading
--then continue looking in body text. If not found, look in
--Overall Index; Card is automatically marked for return.
global whereToGoBack,searchKey
push card
pop card into thisCard
if searchKey is empty then
ask "Search for Keyword in Headings:"
else
ask "Search for Keyword in Headings:" with searchKey
end if
if it is empty then exit headSearch
put it into searchKey
find searchKey in field 4
if the result is "not found" then
find searchKey in field 1
if the result is "not found" then
answer "Continue Search in Text or in Overall Index?" with "Text" or "Index" or "Cancel"
if it is "Cancel" then exit headSearch
if it is "Text" then
find searchKey
if the result is empty then
verifySearch
else
answer "Continue Search in Overall Index?" with "Index" or "Cancel"
if it is "Cancel" then exit headSearch
end if
end if
if it is "Index" then
set lockscreen to true
go to last card of "Nutshell"
send "indexSearch 1" to this card
set lockscreen to false
end if
end if
end if
if the id of this card is not in thisCard then
put thisCard into whereToGoBack
end if
end headSearch
on cardSearch
--Limit search to card. Used for the index or long lists.
--Defines global searchKey to permit continuation of search.
global searchKey
if searchKey is empty then
ask "Enter keyword to look up:"
else
ask "Enter keyword to look up:" with searchKey
end if
put it into searchKey
if searchKey is not empty then
put 0 into notFound
put the id of this card into thisCard
set lockscreen to true
find word searchKey
if the result is "not found" then
put 1 into notFound
end if
if the id of this card is not thisCard
then
go back
put 1 into notFound
end if
if notFound is 1 then
find searchKey
if the result is not empty then
answer quote & searchKey & quote && "not found."
end if
if the id of this card is not thisCard
then
go back
answer quote & searchKey & quote && "not found on this card."
end if
end if
end if
set lockScreen to false
end cardSearch
on returnKey
--enable search to continue if searchKey is defined
global searchKey
if searchKey is not empty and the visible of the msg box is false then
put "find" && quote & searchKey & quote into continueSearch
do ContinueSearch
verifySearch
else
pass returnKey
end if
end returnKey
on verifySearch
--Handle text found in hidden field by displaying FoundLine
--in message box. Called by Return Key & Keyword Requires Ver 1.2
if the version is 1.2 then
if the visible of the foundField is false then
put "put" && the FoundLine into showLine
do showLine
answer "Line Found in Hidden Field. Continue Search?" with "Yes" or "No"
hide msg box
if it is "Yes" then
send returnKey to this card
end if
end if
end if
end verifySearch
on getKey
-- get word at click loc of current field and find it
-- string saved in searchKey so that ReturnKey will allow
-- search to continue. Most of the time, getKey encloses
-- the word clicked in a box; you have to press returnkey for results.
global searchKey
get clickSelect()
if it is empty then exit getkey
put it into searchKey
find searchKey
end getKey
---Link Processing
on PopUp CBnum,topics
--Script called by Topic button to put list of topics
--in popUp field
set lockScreen to true
put "card button" && CBnum into CB
if the style of CB is "rectangle" then
set style of CB to transparent
hide card field "Topics"
hide card button "Topics"
hide card button "Box"
set the hilite of the target to false
put empty into card field "lastTopic"
else
get card field "lastTopic"
if it is not empty then
set hilite of card button ("Topic"&it) to false
set the style of card button it to transparent
end if
set style of CB to rectangle
put CBnum into card field "lastTopic"
put topics into card field "Topics"
show card field "Topics"
show card button "Topics"
show card button "Box"
set the hilite of the target to true
end if
set lockScreen to false
end PopUp
on popDown
--Handler called by Topic box button to hide Topic popUp field.
set lockScreen to true
get card field "lastTopic"
if it is not empty then
set the style of card button it to transparent
set hilite of card button ("Topic"&it) to false
end if
hide card field "Topics"
hide card button "Topics"
hide card button "Box"
put empty into card field "lastTopic"
set lockScreen to false
end popDown
on linkUp
--Handler for linkUp button that displays or hides field "links"
--on section cards
set lockScreen to true
if hilite of the target is true then
hide background button "Links"
hide card field "Links"
set the hilite of the target to false
else
if card field "links" is empty then
beep 2
exit linkup
end if
if card field "lasttopic" is not empty then
send "popdown" to card button "box"
end if
show background button "Links"
show card field "Links"
set the hilite of the target to true
end if
set lockScreen to false
end linkUp
on linkDown
--Called by Diamond Link button to close field Links;
--also called upon closeCard to put away links.
if hilite of background button "LinkUp" is true then
set lockScreen to true
hide background button "Links"
hide card field "Links"
set the hilite of background button "LinkUp" to false
end if
end linkDown
on goLink
--Called by Links field when user clicks on line to select link.
global whereToGoBack
get lineSelect()
if it is empty then exit goLink
put diamondItem (it) into thisLink
push card
pop card into whereToGoBack
if the number of items in thisLink > 2 then
if item 1 of thisLink is empty then
go to card (item 3 of thisLink) of background (item 2 of thisLink)
else
go to card (item 3 of thisLink) of background (item 2 of thisLink) of stack (item 1 of thisLink)
end if
else
if item 1 of thisLink is empty then
go to card (item 2 of thisLink)
else
go to card (item 2 of thisLink) of stack (item 1 of thisLink)
end if
end if
end goLink
on Xref cardName,stackName
--called by forward references; saves current card.
global whereToGoBack
push card
pop card into whereToGoBack
if the paramCount > 1 then
go to card (cardName) of stack (StackName)
else
go to card (cardName)
end if
end Xref
---General Button and Field Handlers
on getName stackName
--get word at click loc of field and find the card of that name
get clickSelect()
if the paramcount > 0 then
go to card (it) of stack StackName
else
go to card (it)
end if
end getName
on returnToMark
--Handler called to mark current card or return to previous mark.
--With option key down, both actions are performed.
global whereToGoBack
if the optionKey is down then
if whereToGoBack is not empty then
flash 1
go to whereToGoBack
push recent card
pop card into whereToGoBack
exit returnToMark
end if
end if
visual effect zoom out
if whereToGoBack is empty then
answer "Mark this card?" with "Mark" or "Cancel"
else
if whereToGoBack contains the id of this card then
answer "This is the marked card."
exit returnToMark
end if
answer "Mark this card or Return to previous mark?" with "Mark" or "Return" or "Cancel"
end if
if it is "Cancel" then exit returnToMark
if it is "Mark" then
flash 1
push card
pop card into whereToGoBack
end if
if it is "Return" then
go to whereToGoBack
end if
end returnToMark
on bulb CFnum
--Handler called by light bulb button.
--Shows pop up field while mouse is down.
if the paramCount is 1 then
put "card field" && CFnum into CF
else
put "card field" && the number of the target into CF
end if
show CF
set hilite of the target to true
wait until the mouse is up
hide CF
set hilite of the target to false
end bulb
on showInfo
--Used when card button and card field have same number
--Clicking on the button shows the field. Clicking on it
--again makes the field disappear.
get the number of the target
if the visible of card field (it) is true then
hide card field (it)
set hilite of button (it) to false
else
show card field (it)
set hilite of button (it) to true
end if
end showInfo
on show2Info CF1, CF2
--Same as showInfo but allows multiple fields to be connect to
--the same button. Also used when button and field number don't
--correspond.
if the visible of card field CF1 is true or the visible of card field CF2 is true then
hide card field CF1
hide card field CF2
set hilite of the target to false
else
show card field CF1
show card field CF2
set hilite of the target to true
end if
end show2Info
on arrowPrev
--Called by screen arrow for previous card.
--Goes to previous card of the current background.
go to prev card of this background
repeat until the mouse is up
go to previous card of this background
set lockScreen to false
repeat 10 times
wait 2
if the mouse is up then exit arrowPrev
end repeat
end repeat
end arrowPrev
on arrowNext
--Called by screen arrow for next card.
--Goes to next card of the current background.
go to next card of this background
repeat until the mouse is up
go to next card of this background
set the lockScreen to false
repeat 10 times
wait 2
if the mouse is up then exit arrowNext
end repeat
end repeat
end arrowNext
on topicCardSeek
-- Allow navigation in a topic deck by specifying the card number
-- relative to the section.
ask "Go to what card in this section?" with 1
put it into goToNum
if goToNum is 1 then
go to first card of this background
else
put field 3 into cardNum
if goToNum > last word of cardNum or goToNum < 0 then
exit topicCardSeek
else
put the number of this card into currentCard
put first word of cardNum into currentSeq
if currentSeq < goToNum then
go to card (currentCard + (goToNum-currentSeq))
else
if currentSeq > goToNum then
go to card (currentCard - (currentSeq-goToNum))
else
exit topicCardSeek
end if
end if
end if
end if
end topicCardSeek
on flipThru
--Handler called by FlipThru button, simulating show all cards.
set lockScreen to false
repeat until the mouseClick
go to next card
end repeat
end flipThru
on showNote
--Handler for card button "notes" (asterisk icon)
--Shows or hides note.
if the visible of card field "Notes" is true
then
hide card field "Notes"
else
show card field "Notes"
end if
end showNote
on enterKey
--Handler that prompts user to create Note.
answer "Attach A Note To This Card?" with "OK" or "Cancel"
if it is "OK" then
makeNote
end if
end enterKey
on deleteNote
--Called when note field exists; use it to delete note.
answer "Note Exists. Do You Want to Delete It?" with "Delete" or "Cancel"
if it is "Delete" then
set lockScreen to true
set cursor to 4
choose button tool
click at the loc of card button "Notes"
doMenu "Cut Button"
choose field tool
show card field "Notes"
click at the loc of card field "Notes"
doMenu "cut field"
choose browse tool
set lockScreen to false
put the script of this card into scriptTemp
repeat with J = 1 to the number of lines in scriptTemp
if line J in scriptTemp is "on enterKey" then
delete line J to (J+2) in scriptTemp
set the script of this card to scriptTemp
exit repeat
end if
end repeat
end if
end deleteNote
on goNuts
--Called by Open Nut or Tree buttons to go back up hierarchy.
if the number of this card is 1 then
go to stack "Nutshell"
else
go to first card
end if
end goNuts
on indexScript
answer "Go to Topic Index for this stack or all stacks?" with the short name of this stack or "Overall" or "Cancel"
if it is "overall" then
go to last card of "Nutshell"
else if it is "Cancel" then
exit indexScript
else
go to last card
end if
end indexScript
on showFields
--display all overlapping fields; placed in card handler
repeat with J = 1 to the number of card fields
set visible of card field J to true
end repeat
end showFields
on overlapFields
--hides fields overlapping target field
if the target contains "bkgnd button" then exit overlapFields
if the target contains "card field" then
repeat with J = 1 to the number of card fields
if the number of the target = J then
set visible of card field J to true
else
if visible of card field J is true and the number of the target < J then
set visible of card field J to false
end if
end if
end repeat
global helpLevel
if helpLevel > 0 then
put "Click outside visible box to redisplay others"
end if
else
showFields
end if
end overlapFields
on uncoverFields
if the target contains "card button" then
if hilite of the target is true
then
set the hilite of the target to false
else
set the hilite of the target to true
end if
repeat with J = 1 to 3
if J is not the number of the target then
set hilite of card button J to false
set visible of card field (J*2) to false
set visible of card field (J*2-1) to false
end if
end repeat
put (the number of the target * 2) into targNum
set visible of card field (targNum-1) to true
set visible of card field targNum to true
end if
end unCoverFields
-- Special functions
function lineSelect
--returns the entire line when user clicks on locked field
if the style of the target is "scrolling" then
put 20 into inFromRight
else
put 2 into inFromRight
end if
set the lockText of the target to false
click at (first item of the rect of target), (second item of the clickLoc)
click at (third item of the rect of target)-inFromRight, (second item of the clickLoc) with shiftKey
set cursor to 4
set the lockText of the target to true
if selection is empty then beep
return selection
end lineSelect
function clickSelect
--returns a word when a user clicks on a locked field
--hold down Shift key; and click again to select phrase
set the lockText of the target to false
if the shiftKey is down then
put 1 into doShift
else
put 0 into doShift
end if
click at the ClickLoc
click at the ClickLoc
if doShift is 1 then
--set cursor to 1
wait until the mouseClick
click at the ClickLoc with shiftkey
click at the ClickLoc with shiftkey
end if
set the lockText of the target to true
if selection is empty then beep
return selection
end clickSelect
function lineClicked
--returns a line number of line where users clicks on locked field.
return (((item 2 of the clickloc - item 2 of the rect of the target) div the textHeight of the target) + 1 + trunc (scroll of the target/textHeight of the target))
end lineClicked
function diamondItem String
--replaces the diamond char (215) with a comma
--also deletes spaces before and after diamond
put String into record
put numToChar(215) into diamond
repeat while record contains diamond
put offset(diamond,record) into DiamondChar
put "," into char DiamondChar of record
if DiamondChar is 1 then
delete char DiamondChar+1 of record
else
delete char DiamondChar-1 of record
delete char DiamondChar of record
end if
end repeat
return record
end diamondItem
---- Stack Specific Handlers
on openStack
global IntroExit
push recent card
pop card into it
if "help" is not in it then
put it into IntroExit
end if
setUpMenus
end openStack
on closeStack -- delete the menus we've created using the globals saved in openStack
global menu1
put DeleteMenu(menu1) into menu1 -- clearing global for safety
--placemark
set lockmessages to true
set lockScreen to true
go to card 2
send popdown to this card
set lockMessages to false
end closeStack
on bird buttonToFlash
set lockScreen to true
put the rect of button "Bird" into BirdNest
get the rect of card field "Bird"
set the rect of button bird to (item 1 of it+1), (item 2 of it-20), (item 1 of it + 200), (item 2 of it+8)
show card field "bird"
set lockScreen to false
if the paramCount = 1 then
repeat until the mouseClick
show buttonToFlash
wait 5
hide buttonToFlash
end repeat
show buttonToFlash
else
wait until the mouseClick
end if
hide card field "bird"
set the rect of button "bird" to BirdNest
end bird
on countCards
global topicListEnd
put 1 into topicListEnd
set lockscreen to true
put the id of this card into BeginList
repeat
go to next card of this background
if the id of this card is BeginList then
exit repeat
else
add 1 to topicListEnd
put the id of this card into EndList
end if
end repeat
choose button tool
put 1 into curNum
repeat
put curNum && "of" && topicListEnd into field 3
add 1 to curNum
if the id of this card is EndList then
exit repeat
end if
go to next card of this background
end repeat
set lockScreen to false
end countCards
on exitScript
global IntroExit
get IntroExit
if it contains "Home" or it contains "Help" or it is empty then
answer "Exit to Home or Quit HyperCard?" with "Home" or "Quit" or "Cancel"
else
put it into PreviousStack
answer "Exit to previous stack or Quit HyperCard?" with "Previous" or "Quit" or "Cancel"
end if
if it is "Cancel" then exit exitScript
if it is "quit" then
answer "Are you sure?" with "Yes" or "No"
if it is "yes" then
doMenu "quit hypercard"
end if
else
if it is "Home" then
go home
else
go to previousStack
end if
end if
end exitScript
on FlashButton CorB, buttonID, timesToRepeat
if CorB is "B" then
put "background button " & quote & buttonID & quote into buttonID
else
put "button " & quote & buttonID & quote into buttonID
end if
if the paramCount < 3 then
put 3 into timesToRepeat
end if
repeat timesToRepeat
set hilite of buttonID to true
wait 10
set hilite of buttonID to false
end Repeat
end FlashButton
on displayField fieldNum
set the visible of card field fieldNum to true
set the hilight of the target to true
repeat until the mouseClick
set hilite of the target to true
wait 10
set hilite of the target to false
end Repeat
set the visible of card field fieldNum to false
set the hilight of the target to false
end displayField
on setUpMenus -- display new menus
global menu1, menu2, listOfStacks,stackRef
put 8 into stackRef
put "put NewMenu(" & quote & "Nutshells" & quote & "," & listofStacks &") into menu1" into firstMenu
do firstMenu
if menu1 is 0 then answer("Unable to make menu 'Nutshells'") with "Drat"
--stack Dependent
checkMenu menu1,stackRef,True
end setUpMenus
on doMenu which -- get our menu items from doMenu before HyperCard does...
global listOfCards
visual effect dissolve
if which is in listofCards then
repeat with J = 1 to the number of lines in listofCards
get line J of listofCards
if which is in last word of it then
go to (it)
exit repeat
end if
end repeat
else pass doMenu -- Remember to pass on menu commands you don't trap!
end doMenu
on makeNote
--Called when EnterKey is pressed and note does
--not exist. Creates a note field and asterisk button.
set the cursor to 4
set lockscreen to true
doMenu "new button"
get "card button id" && the id of button "new button"
set the name of it to "notes"
set the style of it to transparent
set the rect of it to 224,27,248,50
set the showName of it to false
set the icon of it to 7077
set the autoHilite of it to true
choose browse tool
set the lockScreen to false
put the number of card fields into CF
put "on mouseUp" & Return & "showNote" & Return & "end mouseUp" into showNoteButton
set the script of card button "Notes" to showNoteButton
set the lockScreen to true
doMenu "new field"
add 1 to CF
set the name of card field CF to "notes"
set the style of card field "notes" to scrolling
set the rect of card field "notes" to 264,28,489,79
choose browse tool
put the script of this card into scriptTemp
put "on enterKey" & Return & "deleteNote" & Return & "end enterKey" & Return before scriptTemp